package net.zjitc.utils.dispatch;

import net.zjitc.utils.ControllerUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

/**
 * Created by Administrator on 2017/11/8.
 */
@WebServlet(name = "net.zjitc.utils.dispatch.DispatchServlet",urlPatterns = "/")
public class DispatchServlet extends HttpServlet {
    Map<String,Method> urlMap = new HashMap();
    Map<Method,Object> methodMap = new HashMap();
    @Override
    public void init() throws ServletException {
        /**
         * 初始化工作
         *1.找到包下面所有.class文件
         *2.找到文件下的所有方法
         *3.判断方法上是否有注释，如果有，将方法放到map集合中
         */
        String packageName = "net.zjitc.controller";
        List classes = new ArrayList();
        try {
            classes = ControllerUtils.getClass(packageName);//获得包下的类集合
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Iterator<Class> iterator = classes.iterator();//获取类集合迭代器
        while (iterator.hasNext()){
            Class clazz = iterator.next();//获得类
            for (Method m:clazz.getMethods()) {//获得类的方法
                URLMapping urlMapping = m.getAnnotation(URLMapping.class);//获得类方法的注释
                if(urlMapping!=null) {//如果注释不为空
                    String url = urlMapping.url();//获得类的注释参数(url)
                    urlMap.put(url, m);//把参数和方法放到键值对中
                    try {
                        Object obj = clazz.newInstance();//生成类的实体类
                        methodMap.put(m,obj);//把方法和实体类放到键值对中
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /**
         * 接受请求
         * 1.获得请求的servlet名
         * 2.在键值对中获得servlet对应的方法名
         * 3.在键值对中获得方法名对应的实体类
         * 4.调用方法
         **/
        String servletPath = req.getServletPath();//获得servlet名
        Method method = urlMap.get(servletPath);//通过servlet名获得方法
        Object obj = methodMap.get(method);//获得实体类

        String str = "";
        try {
           str = (String) method.invoke(obj,req,resp);//调用方法
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        if(str!=null || "".equals(str)){
            if(str.startsWith("Redirect:")){
                resp.sendRedirect(str.substring(9));
            }else {
                req.getRequestDispatcher(str).forward(req,resp);
            }
        }
    }
}
